package org.makcro.sms.services.chat.web.client.widgets;

import java.util.Map;

import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;

/**
 * Base class for particular entity list. Subclasses are responsible for column
 * model of the grid.
 * 
 * @author makcro
 * 
 */
public abstract class EntityListBase<T extends ModelData> extends ContentPanel {

	protected Grid<T>							grid;
	protected ColumnModel						columnModel;

	protected GroupingStore<T>					store;
	protected GroupingView						groupingView;
	protected PagingToolBar						pagingToolBar;
	protected PagingLoader<PagingLoadResult<T>>	pagingLoader;

	public EntityListBase(PagingLoader<PagingLoadResult<T>> loader) {
		super();
		this.pagingLoader = loader;
		initComponents();
	}

	protected void initComponents() {
		// set layout
		setLayout( new FitLayout() );

		getPagingToolBar().bind( getPagingLoader() );
		setBottomComponent( getPagingToolBar() );

		add( getGrid() );
	}

	public Grid<T> getGrid() {
		if (this.grid == null) {
			this.grid = new Grid<T>( getStore(), getColumnModel() );
			this.grid.getSelectionModel().setSelectionMode( SelectionMode.SINGLE );
			this.grid.setView( getGroupingView() );
			this.grid.disableTextSelection( false );
			this.grid.setLoadMask( true );
			this.grid.setAutoExpandColumn( "text" );
			this.grid.addListener( Events.Attach, new Listener<GridEvent<T>>() {

				@Override
				public void handleEvent(GridEvent<T> be) {
					// setup paging params
					PagingLoadConfig pagingLoadConfig = new BasePagingLoadConfig();
					pagingLoadConfig.setLimit( 50 );
					pagingLoadConfig.setOffset( 0 );

					Map<String, Object> state = grid.getState();
					if (state.containsKey( "offset" )) {
						int offset = (Integer) state.get( "offset" );
						int limit = (Integer) state.get( "limit" );
						pagingLoadConfig.setOffset( offset );
						pagingLoadConfig.setLimit( limit );
					}
					// load data
					getPagingLoader().load();
				}
			} );
		}
		return grid;
	}

	public GroupingStore<T> getStore() {
		if (store == null) {
			store = new GroupingStore<T>( this.pagingLoader );
		}
		return store;
	}

	public GroupingView getGroupingView() {
		if (this.groupingView == null) {
			this.groupingView = new GroupingView();
			this.groupingView.setShowGroupedColumn( true );
			this.groupingView.setForceFit( true );

		}
		return groupingView;
	}

	public PagingToolBar getPagingToolBar() {
		if (this.pagingToolBar == null) {
			pagingToolBar = new PagingToolBar( 50 );
		}
		return pagingToolBar;
	}

	public PagingLoader<PagingLoadResult<T>> getPagingLoader() {
		return pagingLoader;
	}

	public abstract ColumnModel getColumnModel();

}